//
//  SQFoundationSafeHeader.h
//
//  Created by jxz on 2020/4/8.
//  Copyright © 2020 . All rights reserved.
//


//#import "NSObject+Safe.h"
//#import "NSString+Safe.h"
//#import "NSMutableString+Safe.h"
//#import "NSArray+Safe.h"
//#import "NSMutableArray+Safe.h"
//#import "NSDictionary+Safe.h"
//#import "NSMutableDictionary+Safe.h"
//#import "NSURL+Safe.h"


/**** 常用容器有效判断 ****/

#define IsEmpty(str)            (str == nil || ![str respondsToSelector:@selector(isEqualToString:)] || [str isEqualToString:@""])
#define IsArray(obj)            (obj && [obj isKindOfClass:[NSArray class]] && [(NSArray *)obj count])
#define IsDictionary(obj)       (obj && [obj isKindOfClass:[NSDictionary class]] && [(NSDictionary *)obj count])


/**** NSobject保护 ****/

// 判断obj是否为className子类
#define SQ_Object_Is_Class(obj,className) [obj isKindOfClass:className]
// 判断是否为className类型
#define SQ_Object_Is_ClassMember(obj,className) [obj isMemberOfClass:className]
// 是否NSobject类型
#define SQ_Object_Class(obj) SQ_Object_Is_Class(obj,[NSObject class])
// 不为空判断
#define SQ_Object_Not_Null(obj) ((obj != nil) && ((NSNull *)obj != [NSNull null]))
// 为空判断
#define SQ_Object_Is_Null(obj) ((obj == nil) || ((NSNull *)obj == [NSNull null]))
// 是否有效，不为空，且是NSobject类型
#define SQ_Object_Is_Valid(obj) ((SQ_Object_Not_Null(obj)) && (SQ_Object_Class(obj)))
// 是否无效，或为空，或不是NSobject
#define SQ_Object_Not_Valid(obj) ((SQ_Object_Is_Null(obj)) || (!SQ_Object_Class(obj)))


/**** 字符串保护 ****/

// 字符串是NSString类型
#define SQ_Str_Class(str) SQ_Object_Is_Class(str,[NSString class])
// 字符串有效，(考虑字符串长度) 不为空，且是NSString类型，且count值大于0
#define SQ_Str_Is_Valid(str) ((SQ_Object_Not_Null(str)) && (SQ_Str_Class(str)) && ([(NSString *)str length] > 0))
// 字符串有效 (不考虑字符串长度)
#define SQ_Str_Is_Valid_ExceptEmpty(str) ((SQ_Object_Not_Null(str)) && (SQ_Str_Class(str)))
// 字符串无效
#define SQ_Str_Not_Valid(str) ((SQ_Object_Is_Null(str)) || (!SQ_Str_Class(str)) || ([(NSString *)str length] <= 0))
// 字符串赋值保护
#define SQ_Str_Protect(str) (IsEmpty(str) ? @"" : (str))
// 字符串拼接保护
#define SQ_Str_AppendString(str,sub) SQ_Object_Is_ResponseSelector(str,@selector(appendString:)) ? [str performSelector:@selector(appendString:) withObject:sub] :0
// 字符串是NSMutableString类型
#define SQ_Str_Is_Mutable(mstr) ((SQ_Object_Not_Null(mstr)) && (SQ_Str_Class(mstr)) &&([NSStringFromClass(mstr.superclass) isEqualToString:@"NSMutableString"]))


/**** 数组保护 ****/

// 数组是否NSArray类型
#define SQ_Ary_Class(ary) SQ_Object_Is_Class(ary, [NSArray class])
// 数组有效， (考虑数组长度) 不为空，且是NSArray类型，且count值大于0
#define SQ_Ary_Is_Valid(ary) ((SQ_Object_Not_Null(ary)) && (SQ_Ary_Class(ary)) && ([(NSArray *)ary count] > 0))
// 数组有效，（不考虑数组长度）
#define SQ_Ary_Is_Valid_ExceptEmpty(ary) ((SQ_Object_Not_Null(ary)) && (SQ_Ary_Class(ary)))
// 数组有效，是否NSMutableArray类型
#define SQ_mAry_Class(mary) SQ_Object_Is_Class(mary,[NSMutableArray class])
// 数组有效 ，是否NSMutableArray类型 不为空，且count值大于0
#define SQ_mAry_Is_Valid(mary) ((SQ_Object_Not_Null(mary)) && (SQ_mAry_Class(mary)) && ([(NSMutableArray *)mary count] > 0))
// 数组有效 ，是否NSMutableArray类型 没元素也是有效数组
#define SQ_mAry_Is_Valid_ExceptEmpty(mary) ((SQ_Object_Not_Null(mary)) && (SQ_mAry_Class(mary)))
// 数组获取元素保护
#define SQ_Ary_GetObject(array,index) (SQ_Ary_Is_Valid(array) && index<((NSArray *)array).count) ? ((NSArray *)array)[index] : nil
// 数组删除元素保护
#define SQ_Ary_RemoveObject(array,index) (SQ_mAry_Is_Valid(array) && index<((NSMutableArray *)array).count) ? [(NSMutableArray *)array removeObjectAtIndex:index] : 0
// 数组添加元素保护
#define SQ_Ary_AddObject(array,value) (SQ_mAry_Is_Valid_ExceptEmpty(array) && SQ_Object_Is_Valid(value)) ? [(NSMutableArray *)array addObject:value] : 0
// 数组插入元素保护
#define SQ_Ary_InsertAtIndex(array,index,value) ((SQ_mAry_Is_Valid_ExceptEmpty(array)) && SQ_Object_Is_Valid(value) && index<((NSMutableArray *)array).count) ? [(NSMutableArray *)array insertObject:value atIndex:index] : 0
// 数组插入元素保护，index不合法可以在队列末尾插入
#define SQ_Ary_InsertAtIndexCanInLast(array,index,value) ((SQ_mAry_Is_Valid_ExceptEmpty(array)) && SQ_Object_Is_Valid(value)) ? (index<((NSMutableArray *)array).count ? [(NSMutableArray *)array insertObject:value atIndex:index] : [(NSMutableArray *)array addObject:value]) : 0
// 数组添加数组保护
#define SQ_Ary_AddArray(arrayOrg,arraySub) (SQ_mAry_Is_Valid_ExceptEmpty(arrayOrg) && SQ_Ary_Is_Valid(arraySub)) ? [(NSMutableArray *)arrayOrg addObjectsFromArray:(NSArray *)arraySub] : 0
// 数组替换元素保护
#define SQ_Ary_ReplaceAtIndex(array,index,value) (SQ_mAry_Is_Valid(array)) && SQ_Object_Is_Valid(value) && index<((NSMutableArray *)array).count ? [(NSMutableArray *)array replaceObjectAtIndex:index withObject:value] : 0


/**** 字典保护 ****/

// 字典是NSDictionary类型
#define SQ_Dic_Class(dic) SQ_Object_Is_Class(dic,[NSDictionary class])
// 字典有效，(考虑数组长度) 不为空，且是NSDictionary类型，且count值大于0
#define SQ_Dic_Is_Valid(dic) ((SQ_Object_Not_Null(dic)) && (SQ_Dic_Class(dic)) && (((NSDictionary *)dic).count > 0))
// 字典有效，(不考虑字典长度)
#define SQ_Dic_Is_Valid_ExceptEmpty(dic) ((SQ_Object_Not_Null(dic)) && (SQ_Dic_Class(dic)))
// 字典是NSMutableDictionary类型
#define SQ_mDic_Class(mdic) SQ_Object_Is_Class(mdic,[NSMutableDictionary class])
// 字典有效，(考虑字典长度)  不为空，且是NSMutableDictionary类型，且count值大于0
#define SQ_mDic_Is_Valid(mdic) ((SQ_Object_Not_Null(mdic)) && (SQ_mDic_Class(mdic)) && (((NSMutableDictionary *)mdic).count > 0))
// 字典有效，(不考虑字典长度)
#define SQ_mDic_Is_Valid_ExceptEmpty(mdic) ((SQ_Object_Not_Null(mdic)) && (SQ_mDic_Class(mdic)))
// 字典获取元素保护
#define SQ_Dic_SafeGetValue(dic,key) ((SQ_Dic_Is_Valid(dic) && SQ_Object_Is_Valid(key) && [key conformsToProtocol:@protocol(NSCopying)]) ? ((NSDictionary *)dic)[key] : nil)
// 字典获取元素 没有找到取默认值
#define SQ_Dic_SafeGetValue1(dic,key,defautValue) ((SQ_Dic_Is_Valid(dic) && SQ_Object_Is_Valid(key) && [key conformsToProtocol:@protocol(NSCopying)]) ? ((NSDictionary *)dic)[key] : defautValue)
//// 字典获取元素 没有找到取默认值 指定类型
#define SQ_Dic_SafeGetValue2(dic,key,defautValue,className) ((SQ_Dic_Is_Valid(dic) && SQ_Object_Is_Valid(key) && [key conformsToProtocol:@protocol(NSCopying)]) ? ( SQ_Object_Is_Class(((NSDictionary *)dic)[key],className) ? ((NSDictionary *)dic)[key] : defautValue) : defautValue)

// 字典添加元素保护
#define SQ_Dic_SafeSetValue(dic,key,value) (SQ_mDic_Class(dic) && (NSNull *)value != [NSNull null] && SQ_Object_Is_Valid(key) && [key conformsToProtocol:@protocol(NSCopying)]) ? ((NSMutableDictionary *)dic)[key] = value : 0


/**** NSURL保护 ****/

// URL创建 不会对url编码
#define SQ_URL_Create(str) [NSURL URLWithString:SQ_Str_Protect(str)]
// URL创建 如果url未被编码 对url编码
// 对URL中的参数单独编码
#define SQ_URLParam_Encode(str) [SQ_Str_Protect(str) stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"?!@#$^&%*+,:;='\"`<>()[]{}/\\| "].invertedSet]

